﻿using Brc_DSB.GetWay.Model;
using Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Brc_DSB.GetWay.Consul
{
    public static class AppBuilderExtensions
    {
        public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IApplicationLifetime lifetime, ConsulEntity consulEntity, List<ServiceEntity> serviceList)
        {
            //请求注册的 Consul 地址
            var consulClint = new ConsulClient(c => c.Address = new Uri($"http://{consulEntity.ConsulIP}:{consulEntity.ConsulPort}"));
            if (serviceList != null && serviceList.Any())
            {
                var list = new List<AgentServiceRegistration>();
                serviceList.ForEach(serviceEntity =>
                {
                    var httpCheck = new AgentServiceCheck()
                    {
                        DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(10),//服务启动多久后注册
                        Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔，或者称为心跳间隔
                        HTTP = $"http://{serviceEntity.IP}:{serviceEntity.Port}{serviceEntity.HealthAddress}",//健康检查地址
                        Timeout = TimeSpan.FromSeconds(10)
                    };
                    var registration = new AgentServiceRegistration()
                    {
                        Checks = new[] { httpCheck },
                        ID = $"{serviceEntity.ServiceName}-{serviceEntity.IP}:{serviceEntity.Port}",
                        Name = serviceEntity.ServiceName,
                        Address = serviceEntity.IP,
                        Port = serviceEntity.Port,
                        Tags = new[] { $"urlperfix-/{serviceEntity.ServiceName}" }//添加 urlprefix-/servicename 格式的 tag 标签，以便 Fabio 识别
                    };
                    list.Add(registration);
                    //服务启动时注册，内部实现其实就是使用 Consul API 进行注册（HttpClient发起）

                });
                lifetime.ApplicationStarted.Register(() =>
                {
                    //consulClint.Agent.ServiceRegister(list.FirstOrDefault()).Wait();
                    list.ForEach(i => { consulClint.Agent.ServiceRegister(i).Wait(); });                   
                });


                lifetime.ApplicationStopping.Register(() =>
                {
                    //consulClint.Agent.ServiceDeregister(list.FirstOrDefault().ID).Wait();
                    list.ForEach(i => { consulClint.Agent.ServiceDeregister(i.ID).Wait(); });                                        
                });
            }
            return app;
        }
    }
}
